home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 1.iso / ARGONET / PD / GRAPHICS / GIF2RPC.SPK / source / s / map8_quick < prev   
Text File  |  1996-01-11  |  5KB  |  151 lines

  1. ; map8_quick.s
  2. ; MACHINE:     RISC OS
  3. ; LANGUAGE:    OBJASM assembler
  4. ; AUTHOR:      Cy Booker, cy@cheepnis.demon.co.uk
  5. ; LICENSE:     FreeWare, Copyright (c) Cy Booker 1995
  6. ; PURPOSE:     Given an arbitary 48-bit colour, what is the closest 8-bit colour number?
  7. ;             assuming the default 256 colour palette
  8.  
  9.         GET     OS:Hdr.os
  10.  
  11. ;
  12. ; in middle we have |intensity-difference| <-- 0x3fff
  13. ; so |i|^2 <= 0xfff8001
  14. ; and so |d|^2 <= 3.|i|^2 <= 0x2ffe8003
  15. ; so total scale must be < 2^32/(|d|^2) , ie < ~5
  16. ; but this does not leave enough accuracy really, so we shift by a bit
  17. ;
  18. ; the weights we want are:
  19. ;       Red     * 0.212671 *358 ~=  76 /128 ~= 0x0.98
  20. ;       Green   * 0.715160 *358 ~= 256 /128 ~= 0x2.00
  21. ;       Blue    * 0.072169 *358 ~=  26 /128 ~= 0x0.34
  22. ;
  23. ; note we will use the *358 because it makes the inline multiplies very quick
  24. ; even though we have to `divide' by 128 (eg 0x2ffe8003 * 358 / 128 < 2^32
  25. ;
  26.  
  27.         EXPORT  map_scaled_rgb_to_8bpp_colour_number_quick
  28.  
  29.         AREA |ARM$$code|, CODE, READONLY
  30.  
  31.         ROUT
  32.  
  33. str     RN      a1
  34. orig_r  RN      a2
  35. orig_g  RN      a3
  36. orig_b  RN      a4
  37. hi_r    RN      v1
  38. hi_g    RN      v2
  39. hi_b    RN      v3
  40. dmin    RN      v4
  41. tint    RN      v5
  42. d       RN      v6
  43. t       RN      ip
  44. r       RN      orig_r          ; implicit r < g
  45. g       RN      orig_g          ; implicit r < g < b
  46. b       RN      orig_b          ; implicit     g < b
  47. best    RN      str
  48.  
  49. ;
  50. ; In    R0 -> structure
  51. ;       R1 = red nominally [0, 0xffff], but clipped as necessary
  52. ;       R2 = green nominally [0, 0xffff], but clipped as necessary
  53. ;       R3 = blue nominally [0, 0xffff], but clipped as necessary
  54. ; Out   R0 <-- palette entry %BGgRbrTt (bits 8-31 are zero)
  55. ;       structure[0] = error in approximating red intensity
  56. ;       structure[1] = error in approximating green intensity
  57. ;       structure[2] = error in approximating blue intensity
  58. ;
  59. ;
  60. ; this algorithm takes as a first approximation the most significant two
  61. ; bits of each primary
  62. ; this is NOT always the best approximation, and tends to make blacker colours
  63. ; the test8bpp program seems to show that we get this wrong 328/1000 times
  64. ;
  65.  
  66.         ROUT
  67.  
  68. map_scaled_rgb_to_8bpp_colour_number_quick
  69.  
  70.         STMFD   sp!, {a1, v1-v6, lr}                    ; store a1 just so have one word of local stack
  71.         MOV     lr, #0xff00
  72.         ORR     lr, lr, #0xff
  73.         CMP     orig_r, #0x10000                        ; ensure in range [0, 0xffff]
  74.         MOVHS   orig_r, #0
  75.         MOVGE   orig_r, lr
  76.         CMP     orig_g, #0x10000
  77.         MOVHS   orig_g, #0
  78.         MOVGE   orig_g, lr
  79.         CMP     orig_b, #0x10000
  80.         MOVHS   orig_b, #0
  81.         MOVGE   orig_b, lr
  82. ;
  83.         AND     hi_r, orig_r, #&c000                    ; two bits of output
  84.         ORR     hi_r, hi_r, hi_r, LSR #4
  85.         ORR     hi_r, hi_r, hi_r, LSR #8                ; and this is the real intensity
  86. ;
  87.         AND     hi_g, orig_g, #&c000                    ; repeat for green
  88.         ORR     hi_g, hi_g, hi_g, LSR #4
  89.         ORR     hi_g, hi_g, hi_g, LSR #8
  90. ;
  91.         AND     hi_b, orig_b, #&c000                    ; repeat for blue
  92.         ORR     hi_b, hi_b, hi_b, LSR #4
  93.         ORR     hi_b, hi_b, hi_b, LSR #8
  94. ;
  95.         SUB     r, orig_r, hi_r                         ; r= colour to match tints to
  96.         SUB     g, orig_g, hi_g
  97.         SUB     b, orig_b, hi_b
  98. ;
  99.         MOV     tint, #&3300
  100.         ORR     tint, tint, #&33
  101.         MOV     dmin, #&ffffffff
  102.  
  103. 0
  104.         SUBS    t, r, tint                              ; how different is it?
  105.         RSBMI   t, t, #0                                ; makes multiply faster
  106.         MUL     lr, t, t
  107.         ; scale for red ... |r|^2 * (0.212671 * 358 / 128) = 0x0.98
  108.         MOVS    lr, lr, LSR #1
  109.         ADC     d, lr, lr, LSR #3                       ; |r|^2 * 0x0.9
  110.         ADD     d, d, lr, LSR #4                        ; |r|^2 * 0x0.98
  111.  
  112.         SUBS    t, g, tint
  113.         RSBMI   t, t, #0
  114.         MULNE   lr, t, t
  115.         ; scale for green ... |g|^2 * (0.715160 * 358 / 128) = 0x2.00
  116.         ADDNE   d, d, lr, LSL #1                        ; |g|^2 * 0x2
  117.  
  118.         SUBS    t, b, tint
  119.         RSBMI   t, t, #0
  120.         MULNE   lr, t, t
  121.         ; scale for blue ... |b|^2 * (0.072169 * 358 / 128) = 0x0.34
  122.         ADDNE   d, d, lr, LSR #3                        ; |b|^2 * 0x0.2
  123.         ADDNE   d, d, lr, LSR #4                        ; |b|^2 * 0x0.3
  124.         ADDNE   d, d, lr, LSR #6                        ; |b|^2 * 0x0.34
  125.  
  126.         CMP     d, dmin
  127.         MOVLO   dmin, d                                 ; .LO. so that chooses lighter tints
  128.         MOVLO   best, tint                              ; because most significant bits are 'dark'
  129.  
  130.         SUB     tint, tint, #&1100
  131.         SUBS    tint, tint, #&11
  132.         BGE     %BT0
  133.  
  134.         SUB     r, r, best
  135.         SUB     g, g, best
  136.         SUB     b, b, best
  137.         LDMFD   sp!, {lr}
  138.         STMIA   lr, {r, g, b}                           ; store error
  139.         AND     a1, best, #&03
  140.         ORR     a1, a1, hi_g, LSL #3                    ; a1= %0Gg000Tt
  141.         MOVS    t, hi_b, LSL #25
  142.         ORRCS   a1, a1, #&80
  143.         ORRMI   a1, a1, #&08                            ; a1= %BGg0b0Tt
  144.         MOVS    t, hi_r, LSL #25
  145.         ORRCS   a1, a1, #&10
  146.         ORRMI   a1, a1, #&04                            ; a1= %BGgRbrTt
  147.         AND     a1, a1, #&ff                            ; clear upper garbage
  148.         LDMFD   sp!, {v1-v6, pc}^
  149.  
  150.   END
  151.